package com.kgc.itrip.controller;

import com.kgc.itrip.common.Constants;
import com.kgc.itrip.common.DtoUtil;
import com.kgc.itrip.common.EmptyUtils;
import com.kgc.itrip.common.Page;
import com.kgc.itrip.component.SystemConfig;
import com.kgc.itrip.component.ValidationToken;
import com.kgc.itrip.dto.Dto;
import com.kgc.itrip.pojo.ItripImage;
import com.kgc.itrip.pojo.ItripUser;
import com.kgc.itrip.service.ItripCommentService;
import com.kgc.itrip.service.ItripImageService;
import com.kgc.itrip.vo.ItripImageVO;
import com.kgc.itrip.vo.comment.ItripAddCommentVO;
import com.kgc.itrip.vo.comment.ItripListCommentVO;
import com.kgc.itrip.vo.comment.ItripScoreCommentVO;
import com.kgc.itrip.vo.comment.ItripSearchCommentVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Api(value = "酒店品论的控制器")
@Slf4j
@RestController
@RequestMapping("/api/comment")
public class SystemCommentController {
    @Resource
    private ValidationToken validationToken;
    @Resource
    private ItripCommentService itripCommentService;
    @Resource
    private ItripImageService itripImageService;
    @Resource
    private SystemConfig systemConfig;

    @ApiOperation(value = "新增评论接口",
            httpMethod = "POST",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "100003 : 新增评论失败" +
            "100004 : 不能提交空，请填写评论信息"+
            "100005 : 新增评论，订单ID不能为空"+
            "100000 : token失效，请重登录",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @PostMapping(value= "/add")
    public Dto<Object> add(@RequestBody ItripAddCommentVO itripAddCommentVO,HttpServletRequest request){
        if(EmptyUtils.isEmpty(itripAddCommentVO)
            || itripAddCommentVO.getHotelId()==null || itripAddCommentVO.getHotelId()==0){
            return DtoUtil.returnSuccess("不能提交空，请填写评论信息","100004");
        }
        if(itripAddCommentVO.getOrderId()==null || itripAddCommentVO.getOrderId()==0){
            return DtoUtil.returnSuccess("新增评论，订单ID不能为空","100005");
        }
        //要验证用户登录先要获取token，user-agent
        //1.获取token
        String token = request.getHeader("token");
        //2.获取user-agent
        String agent = request.getHeader("User-Agent");
        //3.验证用户是否登录
        boolean validate = validationToken.validate(agent,token);
        if (!validate){//说明没有登录
            return DtoUtil.returnFail("token失败，请重新登录","100000");
        }
        ItripUser currentUser = validationToken.getCurrentUser(token);
        try{
            itripCommentService.itriptxAddItripComment(itripAddCommentVO,currentUser);
            return DtoUtil.returnSuccess("评论添加成功");
        }catch (Exception e){
            e.printStackTrace();
            return DtoUtil.returnFail("品论添加失败","100003");
        }

    }


    @ApiOperation(value = "删除传递图片名称",
            httpMethod = "POST",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "100010:文件不存在，删除失败" +
            "100000 : token失效，请重登录",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @PostMapping(value= "/delpic")
    public Dto delPic(@ApiParam(value = "图片名称",required = true,name="imgName")
                      @RequestParam String imgName,HttpServletRequest request){
        //要验证用户登录先要获取token，user-agent
        //1.获取token
        String token = request.getHeader("token");
        //2.获取user-agent
        String agent = request.getHeader("User-Agent");
        //3.验证用户是否登录
        boolean validate = validationToken.validate(agent,token);
        if (!validate){//说明没有登录
            return DtoUtil.returnFail("token失败，请重新登录","100000");
        }
        //构建需要删除的文件对象
        File deFile = new File(systemConfig.getFileUploadPathString()+File.separator+imgName);
        if(!deFile.exists()){
            return DtoUtil.returnFail("文件不存在，删除失败","100010");
        }
        //如果走到这里删除图片文件
        boolean isDelete = deFile.delete();
        if(isDelete){
            return DtoUtil.returnSuccess();

        }
        return DtoUtil.returnFail("系统异常:文件删除日常","100010");
    }

    @ApiOperation(value = "据图片上传接口",
            httpMethod = "POST",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "100006 : 文件上传失败" +
            "100007 : 上传的文件数不正确，必须是大于1小于等于4"+
            "100008 : 请求的内容不是上传文件的类型"+
            "100009 : 文件大小超限",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @PostMapping(value= "/upload")
    public Dto<List<String>> upload(HttpServletRequest request, HttpServletResponse response){
        //由于储存出错是上传到前端的L
        List<String> hasError = null;
        List<String> result = new ArrayList<>();//存储访问路径
        //返回的map集合中的key值是flag,和前端已经约定好了的
        //要验证用户登录先要获取token，user-agent
        //1.获取token
        String token = request.getHeader("token");
        //2.获取user-agent
        String agent = request.getHeader("User-Agent");
        //3.验证用户是否登录
        boolean validate = validationToken.validate(agent,token);
        if (!validate){//说明没有登录
            return DtoUtil.returnFail("token失败，请重新登录","100000");
        }
        //构建Resolver
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        boolean isMultipart = multipartResolver.isMultipart(request);
        if(!isMultipart){
            return DtoUtil.returnFail("请求的类容不是上传文件的类型","100008");
        }
        //判断是否上传
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        if(!(fileMap.size()>0 && fileMap.size()<=4)){
            return DtoUtil.returnFail("上传的文件数不正确，必须是大于1小于等于4","100007");
        }
        //获取文件和大小
        Iterator<String> fileNames = multipartRequest.getFileNames();
        hasError = new ArrayList<>();
        while (fileNames.hasNext()){
            String fileName = null;
            try {
                MultipartFile file = multipartRequest.getFile(fileNames.next());
                assert file != null;
                long size = file.getSize();
                if(size>5*1024*1024){
                    hasError.add("上传文件"+fileName+"大小超过5M");
                    continue;
                }
                fileName = file.getOriginalFilename();
                //获取文件的后缀
                String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
                //判断文件的后缀名
                String[] suffixArr = {"jpg","jpeg","png"};
                if(!Arrays.asList(suffix).contains(suffix)){
                    hasError.add("上传的文件的："+fileName+"文件类型不正确");
                    continue;
                }
                //上传文件
                //新文件的命名方式：用户的id+当前系统的毫秒数+百万级别的随机数+文件的后追命
                ItripUser currentUser = validationToken.getCurrentUser(token);
                String newFileName = currentUser.getId()+"-"+System.currentTimeMillis()+"-"+(int)(Math.random()*1000000)+suffix;
                //新文件的存储路径
                String fileSavePath = systemConfig.getFileUploadPathString()+File.separator+newFileName;
                File saveFile = new File(fileSavePath);
                file.transferTo(saveFile);
                //获取文件的访问路径
                String visitImgPath = systemConfig.getVisitImgUrlString()+newFileName;
                result.add(visitImgPath);
            } catch (IOException e){
                e.printStackTrace();
                log.error("文件上传异常");
                hasError.add("上传的文件的："+fileName+"文件类型不正确");
                continue;
            }
        }
        if(hasError.isEmpty()){//没有上传错误
            return DtoUtil.returnDataSuccess(result);
        }
        return DtoUtil.returnSuccess(hasError.toString(),result);
    }

    @ApiOperation(value = "据酒店id查询酒店平均分",
            httpMethod = "GET",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "如下：100001 : 获取评分失败" +
            ":100002 : hotelId不能为空",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @GetMapping(value= "gethotelscore/{hotelId}")
    public Dto<ItripScoreCommentVO> getHotelScore(@ApiParam(value = "酒店ID",required = true,name = "hotelId")
                                                  @PathVariable String hotelId){
        if(EmptyUtils.isEmpty(hotelId)){
            return DtoUtil.returnFail("hotelId不能为空","100002");
        }

        try{
            ItripScoreCommentVO scoreCommentVO = itripCommentService.queryItripHotelScore(Long.parseLong(hotelId));
            return DtoUtil.returnDataSuccess(scoreCommentVO);
        }catch (Exception e){
            e.printStackTrace();
            log.error("获取评分失败");
            return DtoUtil.returnFail("获取评分失败","100001");
        }
    }

    @ApiOperation(value = "根据targetId查询评论照片",
            httpMethod = "GET",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "如下：100012 : 获取酒店图片失败 :100013 : 酒店id不能为空",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @GetMapping(value= "/getimg/{targetId}")
    public Dto<List<ItripImageVO>> getImg(@PathVariable String targetId){
        if(EmptyUtils.isEmpty(targetId)){
            return DtoUtil.returnFail("酒店id不能为空","100013");
        }
        Map<String,Object> params = new HashMap<>();
        params.put("type", Constants.IMAGE_TYPE.COMMENT_IMAGE);
        params.put("targetId",targetId);
        try{
            //调用业务逻辑层
            List<ItripImage> itripImageList = itripImageService.getItripImageListByMap(params);
            //创建放回的图片集合
            List<ItripImageVO> imageVOList = new ArrayList<>();
            for (ItripImage itripImage : itripImageList) {
                ItripImageVO imageVO = new ItripImageVO();
                BeanUtils.copyProperties(itripImage,imageVO);
                imageVOList.add(imageVO);
            }
            return DtoUtil.returnDataSuccess(imageVOList);
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询酒店图片失败");
            return DtoUtil.returnFail("获取酒店图片失败","100012");
        }
    }


    @ApiOperation(value = "根据评论类型查询评论列表，并分页显示",
            httpMethod = "POST",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "100020 : 获取评论列表错误",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @PostMapping(value= "getcommentlist")
    public Dto<Page<ItripListCommentVO>> getCommentList(@RequestBody ItripSearchCommentVO itripSearchCommentVO) {
        if(EmptyUtils.isEmpty(itripSearchCommentVO)
                || itripSearchCommentVO.getHotelId()==null || itripSearchCommentVO.getHotelId()==0
                || itripSearchCommentVO.getIsHavingImg()==null
                || itripSearchCommentVO.getIsOk()==null){
            return DtoUtil.returnFail("查询参数不能为空","100999");
        }
        try {
            Map<String,Object> params =new HashMap<>();
            params.put("hotelId",itripSearchCommentVO.getHotelId());
            params.put("isHavingImg",itripSearchCommentVO.getIsHavingImg());
            params.put("isOk",itripSearchCommentVO.getIsOk());
            //调用业务逻辑层
            Page<ItripListCommentVO> itripListCommentVOPage = itripCommentService.queryItripCommentPageByMap(params, itripSearchCommentVO.getPageNo(), itripSearchCommentVO.getPageSize());
            return DtoUtil.returnDataSuccess(itripListCommentVOPage);

        }catch (Exception e){
            e.printStackTrace();
            log.error("系统异常：获取评论列表错误");
            return DtoUtil.returnFail("获取评论列表错误","100020");
        }

    }

    @ApiOperation(value = "根据酒店id查询各类评论数量",
            httpMethod = "GET",notes = " success = ‘true’ | 失败：success = ‘false’ 并返回错误码，" +
            "如下：100014 : 获取酒店总评论数失败" +
            "100015 : 获取酒店有图片评论数失败"+
            "100016 : 获取酒店有待改善评论数失败"+
            "100017 : 获取酒店值得推荐评论数失败"+
            "100018 : 参数hotelId为空",
            protocols = "http",produces = "application/json;charset=UTF-8",
            consumes = "application/json")
    @GetMapping(value= "getcount/{hotelId}")
    public Dto<Map<String,Integer>> getCount(@PathVariable String hotelId) {
        if (EmptyUtils.isEmpty(hotelId)) {
            return DtoUtil.returnFail("参数hotelId为空", "100018");
        }
        //创建map集合对象
        Map<String, Integer> result = new HashMap<>();
        //更具酒店id查询评论
        Map<String, Object> params = new HashMap<>();
        //查询所有的评论
        params.put("hotelId", hotelId);
        try {
            Integer allComment = itripCommentService.getItripCommentCountByMap(params);
            if (allComment == null) {
                return DtoUtil.returnFail("获取酒店总评论数失败","100014");
            }
            result.put("allcomment",allComment);
            //查询值得推荐的评论数量
            params.put("isOk",1);
            Integer isOk = itripCommentService.getItripCommentCountByMap(params);
            if(isOk==null){
                return DtoUtil.returnFail("获取酒店值得推荐评论数失败","100017");
            }
            result.put("isok",isOk);
            //查询有待改善的评论数量
            params.remove("isOk");
            params.put("isOk",0);
            Integer improve = itripCommentService.getItripCommentCountByMap(params);
            if(isOk==null){
                return DtoUtil.returnFail("获取酒店有待改善评论数失败","100016");
            }
            result.put("improve",improve);
            //查询有图片的评论数量
            params.remove("isOk");
            params.put("isHavingImg",1);
            Integer isHavingImg = itripCommentService.getItripCommentCountByMap(params);
            if(isOk==null){
                return DtoUtil.returnFail("获取酒店有图片评论数失败","100015");
            }
            result.put("havingimg",isHavingImg);
            return DtoUtil.returnDataSuccess(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("系统错误");
            return DtoUtil.returnFail("获取酒店总评论数失败", "100014");
        }

    }
}
